【新機能】CloudTrailでS3オブジェクトレベルのアクセスをロギングする
こんにちは、虎塚です。
先日のAWSアップデートによって、CloudTrailでS3オブジェクトレベルのロギングができるようになりましたので、ご紹介します。
これまでもS3バケットレベルでの操作はCloudTrailで記録できましたが、オブジェクトへのアクセスのロギングはサポートされていませんでした。
今回のアップデートで、S3オブジェクトのPutやDeleteといった操作がCloudTailで追跡、記録できるようになりました。
S3オブジェクトレベルのロギングの概要
今回のアップデートに伴い、CloudTrailにイベントセレクタという新しい概念が登場しました。次の流れでイベントを捕捉し、ロギングします。
- アカウント内でなんらかのイベントが起きる
- CloudTrailが全trailでイベントセレクタを評価する
- 各trailは、イベントセレクタの設定にしたがってロギングする (S3バケットとCloudWatch Logsのロググループに配信する)
- イベントセレクタと合致したイベントは、trailが記録する
- イベントセレクタと合致しなかったイベントは、trailが記録しない
2016年11月時点では、1つのtrailに最大5個のイベントセレクタを設定できます。また、1個のイベントセレクタに最大50個のS3バケットとオブジェクトのprefixを指定できます。
イベント
trailが記録対象とするイベントの種類を整理しましょう。イベントセレクタの設定で、捕捉対象にするイベントを定義します。
Data EventとManagement Event
Data Eventは、S3オブジェクトにアクセスするためのGet、Put、DeleteなどのAPI操作によって発生するイベントです。今回の機能アップデートでtrailが捕捉できるようになったのが、このData Eventです。
Data Event以外のすべてのイベントは、Management Eventと呼ばれます。たとえば、次のようなイベントがManagement Eventです。
- API呼び出しで発生するイベント (Data Eventを除く)
- API呼び出しを伴わないイベント
- AWS Management Consoleへのユーザログイン
- CloudTrailでEventTypeが「AwsServiceEvent」と記録されるAWSの内部イベント
たとえば、EC2インスタンスの一覧を取得したり、EC2インスタンスを起動したりするイベントは、Management Eventです。これらは、これまでのCloudTrailでもtrailログに記録されていました。
Read-only EventとWrite-only Event
- Read-only Event: AWSリソースに変更を加えないイベント
- (例) 名前にDescribeやListがついているAPI操作
- Write-only Event: AWSリソースを変更する(変更しうる)イベント
- (例) RunInstances、TerminateInstancesなど
イベントセレクタ
イベントセレクタは、trailに対して設定するイベントのフィルタのようなものです。イベントセレクタは、デフォルトでは次のイベントを捕捉します。
- | read-only Events | write-only Events |
---|---|---|
Data Events | N | N |
Management Events | Y | Y |
S3オブジェクトレベルでのAPI操作は、イベントセレクタの設定をデフォルトから変更してData Eventを捕捉対象にすることで、trailログに記録できるようになります。
注意事項
ベストプラクティスとして、オブジェクトレベルのアクセスをロギング対象にするS3バケットと、ログファイルを配信するS3バケットは分けましょう。同一のバケットにしてしまった場合、ログのPUTによるイベント発生でログがPUTされ、無限ループに陥ります。
動作確認
それでは、イベントセレクタを使ったS3オブジェクトレベルAPI操作のロギングを試してみましょう。
AWSアカウントにすべてのイベントを記録するtrailをすでに設定している場合は、イベントセレクタを設定するためのtrailを新規に追加したほうが、イベントが混ざらなくて動作確認をしやすくなります。
1. trailログ保存用 S3バケットの作成
trailにログを保存させるためのS3バケット (write-only-events) を作成します。
aws s3api create-bucket --bucket write-only-events \ --create-bucket-configuration LocationConstraint=ap-northeast-1
CloudTrailがログファイルを送信できるようにするため、バケットに次のバケットポリシーを付与します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AWSCloudTrailAclCheck20150319", "Effect": "Allow", "Principal": { "Service": "cloudtrail.amazonaws.com" }, "Action": "s3:GetBucketAcl", "Resource": "arn:aws:s3:::write-only-events" }, { "Sid": "AWSCloudTrailWrite20150319", "Effect": "Allow", "Principal": { "Service": "cloudtrail.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::write-only-events/*", "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } } } ] }
aws s3api put-bucket-policy --bucket write-only-events --policy file://policy.json
2. オブジェクト操作監視対象 S3バケットの作成
ステップ1で作成したものとは別のS3バケット (test-20161130) を作成します。
aws s3api create-bucket --bucket test-20161130 \ --create-bucket-configuration LocationConstraint=ap-northeast-1
このバケットに対するAPI操作を、trailがイベントセレクタで捕捉して、ログ保存用S3バケットにログを送信します。
3. trailの作成
東京リージョンにCloudTrailのtrail (test-event-selector) を1個作成します。ログの送信先S3バケットとして、ステップ1で作成したバケットを指定します。
aws cloudtrail create-trail --name test-event-selector --s3-bucket-name write-only-events { "IncludeGlobalServiceEvents": true, "Name": "test-event-selector", "TrailARN": "arn:aws:cloudtrail:ap-northeast-1:123456789012:trail/test-event-selector", "LogFileValidationEnabled": false, "IsMultiRegionTrail": false, "S3BucketName": "write-only-events" }
trailにイベントセレクタがまだ設定されていないことを確認しておきます。
aws cloudtrail get-event-selectors --trail-name test-event-selector { "EventSelectors": [ { "IncludeManagementEvents": true, "DataResources": [], "ReadWriteType": "All" } ], "TrailARN": "arn:aws:cloudtrail:ap-northeast-1:123456789012:trail/test-event-selector" }
4. イベントセレクタの作成
trailにイベントセレクタを作成します。
今回は、ログ出力量を抑えて動作確認を簡単にするため、Write-only Eventだけをイベントセレクタの捕捉対象にします。こうすることで、Get系APIやList系APIの実行がロギングされなくなります。
さらに、Management Eventを対象から除きます。こうすることで、AWSの内部の動作で発生するイベントやユーザのManagement Consoleログイン操作がロギングされなくなります。
[ { "ReadWriteType": "WriteOnly", "IncludeManagementEvents": false, "DataResources": [ { "Type": "AWS::S3::Object", "Values": [ "arn:aws:s3:::test-20161130/" ] } ] } ]
ステップ2で作成したS3バケット (test-20161130) をDataResourcesに指定します。
このようにS3バケットを指定すると、そのバケット内のすべてのオブジェクトに対する操作を記録できます。S3バケットとプリフィックスを指定すると、そのバケット内の特定のオブジェクトに対する操作を記録できます。
aws cloudtrail put-event-selectors --trail-name test-event-selector \ --event-selectors file://event_selector.json { "EventSelectors": [ { "IncludeManagementEvents": true, "DataResources": [ { "Values": [ "arn:aws:s3:::test-20161130/" ], "Type": "AWS::S3::Object" } ], "ReadWriteType": "All" } ], "TrailARN": "arn:aws:cloudtrail:ap-northeast-1:123456789012:trail/test-event-selector" }
trailにイベントセレクタが設定されました。
5. ロギングの開始
trailでのロギングを開始します。
aws cloudtrail start-logging --name arn:aws:cloudtrail:ap-northeast-1:123456789012:trail/test-event-selector
6. S3バケットにファイルを配置
動作確認のため、S3バケット (test-20161130) にオブジェクトを作成したり削除したりしてみましょう。
aws s3api put-object --bucket test-20161130 --key sample.png --body sample.png
S3オブジェクトは、任意のファイルで構いません。
7. trailログの確認
trailログを閲覧して、ステップ6の操作が記録されていることを確認します。trailログがS3バケットに出力されるまで、最大で5分ほど待ちます。AWS Management ConsoleのCloudTrail API Activity履歴では、Management Eventしか表示されないため、今回のようにData Eventの履歴を見るには、S3バケットに出力されたログを直接確認する必要があります。
S3バケット (write-only-events) を確認して、S3オブジェクトのputやdeleteのイベントだけが記録されたCloudTrailログが作成されたことを確認します。
動作確認は以上です。
おわりに
S3オブジェクトをロギングできるようになり、セキュリティや監査の用途でCloudTrailの使い道がさらに広がりました。便利なユースケースをまたご紹介できればと思います。
それでは、また。
参考情報
- CloudTrail の更新 – Amazon S3 オブジェクトレベルの API アクティビティのキャプチャと処理 | Amazon Web Services ブログ
- Amazon Web Services ブログ: Amazon S3 のオペレーションの一部が AWS CloudTrailログに記録されるようになりました
- Configuring Event Selectors for Trails - AWS CloudTrail
- EventSelector - AWS CloudTrail
- 11月30日時点でAWS CLIドキュメントに本機能が未反映だったため、イベントセレクタ作成時の引数についてはAPIドキュメントを参照しました。